#pragma once
#include <functional>
#include <thread>
#include <memory>
#include <atomic>
#include "TaskQueue.h"

const int MAX_TASK_COUNT = 100;

class ThreadPool
{
public:
    // 规定任务类型为void()，我们可以通过c++11不定参数模板来实现一个可接受任何参数的范式函数模板，
    // 这样就是一个可以接收任何任务的任务队列了
    using Task = std::function<void()>;
    // hardware_concurrency 检测硬件性能，给出默认线程数
    ThreadPool(int numThreads = std::thread::hardware_concurrency());
    // 销毁线程池
    ~ThreadPool();

    // 终止所有线程，call_once保证函数只执行一次
    void Stop();

    // 添加任务,普通版本
    void AddTask(const Task &task);

    // 添加任务，右值引用版本
    void AddTask(Task &&task);

private:
    // 停止线程池
    void StopThreadGroup();
    void Start(int numThreads);
    // 一次取出所有事件
    void RunInThreadList();
    // 一次取出一个事件
    void RunInThread();

private:
    // 线程池
    std::list<std::shared_ptr<std::thread>> m_threadGroup;
    // 任务队列
    TaskQueue<Task> m_queue;
    // 原子布尔值
    std::atomic_bool m_running;
    // 辅助变量->call_once
    std::once_flag m_flag;
};